﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace MKAdmin.ToolKit
{
    public static class WebHelper
    {
        #region Session操作
        /// <summary>
        /// 写Session
        /// </summary>
        /// <typeparam name="T">Session键值的类型</typeparam>
        /// <param name="key">Session的键名</param>
        /// <param name="value">Session的键值</param>
        public static void WriteSession<T>(string key, T value)
        {
            if (string.IsNullOrWhiteSpace(key))
                return;
            HttpContext.Current.Session[key] = value;
        }

        /// <summary>
        /// 写Session
        /// </summary>
        /// <param name="key">Session的键名</param>
        /// <param name="value">Session的键值</param>
        public static void WriteSession(string key, string value)
        {
            WriteSession<string>(key, value);
        }

        /// <summary>
        /// 读取Session的值
        /// </summary>
        /// <param name="key">Session的键名</param>        
        public static string GetSession(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                return string.Empty;
            return HttpContext.Current.Session[key] as string;
        }
        /// <summary>
        /// 删除指定Session
        /// </summary>
        /// <param name="key">Session的键名</param>
        public static void RemoveSession(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                return;
            HttpContext.Current.Session.Contents.Remove(key);
        }

        #endregion

        #region Cookie操作
        /// <summary>
        /// 写cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="strValue">值</param>
        public static void WriteCookie(string strName, string strValue)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[strName];
            if (cookie == null)
            {
                cookie = new HttpCookie(strName);
            }
            cookie.Value = strValue;
            HttpContext.Current.Response.AppendCookie(cookie);
        }
        /// <summary>
        /// 写cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="strValue">值</param>
        /// <param name="strValue">过期时间(分钟)</param>
        public static void WriteCookie(string strName, string strValue, int expires)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[strName];
            if (cookie == null)
            {
                cookie = new HttpCookie(strName);
            }
            cookie.Value = strValue;
            cookie.Expires = DateTime.Now.AddMinutes(expires);
            HttpContext.Current.Response.AppendCookie(cookie);
        }
        /// <summary>
        /// 读cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <returns>cookie值</returns>
        public static string GetCookie(string strName)
        {
            if (HttpContext.Current.Request.Cookies != null && HttpContext.Current.Request.Cookies[strName] != null)
            {
                return HttpContext.Current.Request.Cookies[strName].Value.ToString();
            }
            return "";
        }
        /// <summary>
        /// 删除Cookie对象
        /// </summary>
        /// <param name="CookiesName">Cookie对象名称</param>
        public static void RemoveCookie(string CookiesName)
        {
            HttpCookie objCookie = new HttpCookie(CookiesName.Trim());
            objCookie.Expires = DateTime.Now.AddYears(-5);
            HttpContext.Current.Response.Cookies.Add(objCookie);
        }
        #endregion

        #region 获取网页源码
        /// <summary>
        /// 获取网页源码
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public static string GetWebSourceCode(string url)
        {
            string strHTML = "";
            try
            {
                var data = new System.Net.WebClient { }.DownloadData(url); //根据textBox1的网址下载html
                var r_utf8 = new System.IO.StreamReader(new System.IO.MemoryStream(data), Encoding.UTF8); //将html放到utf8编码的StreamReader内
                var r_gbk = new System.IO.StreamReader(new System.IO.MemoryStream(data), Encoding.Default); //将html放到gbk编码的StreamReader内
                var t_utf8 = r_utf8.ReadToEnd(); //读出html内容
                var t_gbk = r_gbk.ReadToEnd(); //读出html内容
                if (!isLuan(t_utf8)) //判断utf8是否有乱码
                {
                    strHTML = t_utf8;
                }
                else
                {
                    strHTML = t_gbk;
                }
            }
            catch (Exception ex)
            {
                strHTML = "URL解析失败";
                LogHelper.Error(ex.Message);
            }
            return strHTML;
        }
        #endregion

        private static bool isLuan(string txt)
        {
            var bytes = Encoding.UTF8.GetBytes(txt);
            //239 191 189
            for (var i = 0; i < bytes.Length; i++)
            {
                if (i < bytes.Length - 3)
                    if (bytes[i] == 239 && bytes[i + 1] == 191 && bytes[i + 2] == 189)
                    {
                        return true;
                    }
            }
            return false;
        }

        /// <summary>
        /// 描述：发送Http请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="data">需要传的数据对象</param>
        /// <param name="method">Http请求方法</param>
        /// <param name="contentType">Http内容类型</param>
        /// <param name="headValueCollection">Http头部内容</param>
        /// <param name="encoding">编码类型</param>
        /// <param name="requestDate"></param>
        /// <returns></returns>
        public static string SubmitForm(string url, object data, string method, string contentType,
            NameValueCollection headValueCollection = null, Encoding encoding = null, DateTime? requestDate = null)
        {
            //读取返回消息
            var result = string.Empty;

            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream reqStream = null;
            Stream resStream = null;

            try
            {
                if (encoding == null) encoding = Encoding.UTF8;
                // get请求拼接url
                if (method.ToUpper() == "GET") url += url.Contains("?") ? "&" : "?" + data.ToUrlData();

                request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = method;
                request.ContentType = contentType;
                //设置为不需要等待服务器允许
                //request.ServicePoint.Expect100Continue = false;
                request.ServicePoint.UseNagleAlgorithm = false;
                request.AllowWriteStreamBuffering = false;
                request.KeepAlive = false;

                if (requestDate.HasValue) request.Date = requestDate.Value;
                if (null != headValueCollection) request.Headers.Add(headValueCollection);
                if (method.ToUpper() == "POST")
                {
                    if (data == null) request.ContentLength = 0;
                    else
                    {
                        var dataArray = encoding.GetBytes(data.ToJson());
                        request.ContentLength = dataArray.Length;
                        reqStream = request.GetRequestStream();
                        reqStream.Write(dataArray, 0, dataArray.Length);
                    }
                }

                response = (HttpWebResponse)request.GetResponse();
                resStream = response.GetResponseStream();
                if (resStream != null)
                {
                    var reader = new StreamReader(resStream, encoding);
                    result = reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("网络请求失败", ex);
            }
            finally
            {
                if (resStream != null) resStream.Close();
                if (reqStream != null) reqStream.Close();
                if (response != null) response.Close();
                if (request != null) request.Abort();
            }

            return result;
        }

        #region Post/Get请求数据
        /// <summary>
        /// Post/Get请求数据
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <param name="data"></param>
        /// <param name="contentType"></param>
        /// <param name="requestMethod"></param>
        /// <param name="connectionLimit"></param>
        /// <returns></returns>
        public static string SendRequest(string requestUrl, string data, NameValueCollection headValueCollection = null,
         string contentType = "application/json", string requestMethod = WebRequestMethods.Http.Post)
        {
            HttpWebRequest httpWebRequest = null;
            string returnData = "";
            try
            {
                httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
                httpWebRequest.Method = requestMethod;
                httpWebRequest.ContentType = "application/json; charset=utf-8";
                httpWebRequest.Proxy = null;
                httpWebRequest.KeepAlive = false;
                httpWebRequest.ServicePoint.UseNagleAlgorithm = false;
                httpWebRequest.AllowWriteStreamBuffering = false;
                httpWebRequest.Accept = "application/json";

                byte[] dataArray = Encoding.UTF8.GetBytes(data);
                httpWebRequest.ContentLength = dataArray.Length;

                if (null != headValueCollection) httpWebRequest.Headers.Add(headValueCollection);

                using (Stream requestStream = httpWebRequest.GetRequestStream())
                {
                    requestStream.Write(dataArray, 0, dataArray.Length);
                    HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                    StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
                    returnData = streamReader.ReadToEnd();

                    streamReader.Close();
                    httpWebResponse.Close();
                }

                httpWebRequest.Abort();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (httpWebRequest != null)
                {
                    httpWebRequest.Abort();
                    httpWebRequest = null;
                }
            }

            return returnData; ;
        }
        #endregion

        /// <summary>
        /// 作者：
        /// 时间：2018.02.08
        /// 描述：将对象转为url的参数
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToUrlData(this object obj)
        {
            var type = obj.GetType();
            var properties = type.GetProperties();
            var data = string.Empty;

            foreach (var propertie in properties)
            {
                var value = propertie.GetValue(obj) ?? string.Empty;
                data += propertie.Name + "=" + value + "&";
            }
            data = data.Length > 0 ? data.Substring(0, data.Length - 1) : data;
            return data;
        }
    }
}
